/*
 * 任务模块
 *
 * 定义任务对象，并以多态的方式组织
 * 用于交给生产消费模型处理
 *
 **/

#pragma once

#include <iostream>
#include "util.hh"
#include "info.hh"

namespace cloud
{

class task
{
public:
    using ptr = std::shared_ptr<task>;

public:
    task() = default;

    virtual void operator()() const
    {
        throw except("can't call operator() on task");
    }
};

class pack_task : public task
{
public:
    using ptr = std::shared_ptr<pack_task>;

public:
    pack_task() = default;

    pack_task(backup_info* i) : info(i)
    {}

    virtual void operator()() const override
    {
        if (!info)
        {
            throw except("task::info ptr is null");
        }

        if (info->ishot)
        {
            util::file(info->bpath).pack(info->ppath).remove();
            info->ishot = false;
        }
        else
        {
            util::file(info->ppath).unpack(info->bpath).remove();
            info->ishot = true;
        }
    }

private:
    backup_info* info;
};

class cb_task : public task
{
public:
    using ptr = std::shared_ptr<cb_task>;
    using handle = std::function<void()>;

public:
    cb_task() = default;

    cb_task(const handle& cb) : _cb(cb)
    {}

    virtual void operator()() const override
    {
        _cb();
    }

    handle _cb;
};

struct task_factory
{
    template<typename task_type, typename... Args>
    static task::ptr create(Args&&... args)
    {
        return std::make_shared<task_type>(std::forward<Args>(args)...);
    }
};

}
